<?php

/**
 *
 * @author Kam
 */
class Application_Model_DAO_Event extends My_DAO_Abstract {

    const DB_EVENT = 'Event';
    const DB_EVENT_INFO = 'EventInfo';
    const DB_EVENT_PLACE = 'EventPlace';

    public function limitEventsByInfoType(Zend_Db_Table_Select $select, array $allowedTypes) {
        return $select->where('ei.type IN (?)', $allowedTypes);
    }

    public function limitEventsByDateFrame(Zend_Db_Table_Select $select, $dateStart, $dateEnd = null) {
        $wheres = array(
            "'$dateStart' <= e.start_date AND e.end_date IS NULL AND '$dateEnd' >= e.start_date",
            "e.end_date IS NOT NULL AND '$dateStart' <= e.end_date AND '$dateEnd' >= e.start_date",
            );
        $select->where('('.implode(') OR (', $wheres).')');
        return $select;
    }

    public function limitEventsByPlace(Zend_Db_Table_Select $select, array $allowedPlaces, $column = 'e.event_place_id') {
        return $select->where($column . ' IN (?)', $allowedPlaces);
    }

    /*
     * CRUD
     */

    public function deleteEventByColumn($id, $column = 'event_id') {
        $where = $this->getDbTable()->getAdapter()->quoteInto($column . ' = ?', $id);
        return $this->getDbTable()->delete($where);
    }

    public function deleteEventPlaceByColumn($id, $column = 'event_place_id') {
        $event = $this->getEventPlaceByColumn($id, $column);
        $where = $this->getDbTable()->getAdapter()->quoteInto('event_place_id = ?', $event['event_place_id']);
        $this->getDbTable()->delete($where);
        $daoImage = new Application_Model_DAO_Image();
        $daoImage->delete($event['image_id']);
        return $this->getDbTable(self::DB_EVENT_PLACE)->delete($event['event_place_id']);
    }

    public function deleteEventInfoByColumn($id, $column = 'event_info_id') {
        $event = $this->getEventPlaceByColumn($id, $column);
        $where = $this->getDbTable()->getAdapter()->quoteInto('event_info_id = ?', $event['event_info_id']);
        $this->getDbTable()->delete($where);
        $daoImage = new Application_Model_DAO_Image();
        $daoImage->delete($event['image_id']);
        return $this->getDbTable(self::DB_EVENT_INFO)->delete($event['event_info_id']);
    }

    public function getEventByColumn($id, $column = 'event_id') {
        // @todo
        return $this->getDbTable(self::DB_EVENT)->getByColumn($id, $column);
    }

    public function getEventPlaceByColumn($id, $column = 'event_place_id') {
        if (stripos($column, '.') === false) {
            $column = 'ep.' . $column;
        }
        return $this->getDbTable(self::DB_EVENT_PLACE)->select()
                        ->from(array('ep' => 'event_place'))
                        ->joinLeft(array('i' => 'image'), 'ep.image_id=i.image_id', array('image_code' => 'code'))
                        ->where($column . ' = ?', $id)
                        ->query()->fetch();
    }

    public function getEventInfoByColumn($id, $column = 'event_info_id') {
        return $this->getDbTable(self::DB_EVENT_INFO)->getByColumn($id, $column);
    }

    public function getAllPlaces() {
        return $this->getDbTable(self::DB_EVENT_PLACE)->select()
                        ->from(array('ep' => 'event_place'))
                        ->joinLeft(array('i' => 'image'), 'ep.image_id = i.image_id', array('image_code' => 'code'))
                        ->order('ep.event_place_id DESC');
    }

    public function getAllInfos() {
        return $this->getDbTable(self::DB_EVENT_INFO)->select()
                        ->from(array('ei' => 'event_info'))
                        ->joinLeft(array('i' => 'image'), 'ei.image_id = i.image_id', array('image_code' => 'code'))
                        ->order('ei.event_info_id DESC');
    }

    public function getAllEvents() {
        $select = $this->getDbTable(self::DB_EVENT)->select()
                ->from(array('e' => 'event'), array('event_code' => 'code', '*'))
                ->joinLeft(array('ei' => 'event_info'), 'e.event_info_id=ei.event_info_id', array('info_name' => 'name', 'info_desc' => 'description', 'info_code' => 'code', 'info_type' => 'type', '*'))
                ->joinLeft(array('ep' => 'event_place'), 'e.event_place_id=ep.event_place_id', array('place_name' => 'name', 'place_desc' => 'description', 'place_code' => 'code', 'place_type' => 'type', '*'))
                ->joinLeft(array('i1' => 'image'), 'ei.image_id=i1.image_id', array('info_image_code' => 'code'))
                ->joinLeft(array('i2' => 'image'), 'ep.image_id=i2.image_id', array('place_image_code' => 'code'))
                ->order('e.event_id DESC');
        return $select;
    }

    public function updateEventInfo($data, $extra = null, $id = 0, $column = 'event_info_id') {
        $record = $this->_buildEventInfo($data, $extra);
        $where = $this->getDbTable(self::DB_EVENT_INFO)->getAdapter()->quoteInto($column . ' = ?', $id);
        $tmp = $this->getDbTable(self::DB_EVENT_PLACE)->getByColumn($id, $column);
        $this->_updateImage($record, 'event_imfo', $tmp['event_place_id']);
        return $this->getDbTable(self::DB_EVENT_INFO)->update($record, $where);
    }

    public function addEventInfo($data, $extra = null) {
        $record = $this->_buildEventInfo($data, $extra);
        $recordId = $this->getDbTable(self::DB_EVENT_INFO)->insert($record);
        $this->_updateImage($record, 'event_info', $recordId);
        return $this->getDbTable(self::DB_EVENT_INFO)->get($recordId);
    }

    public function updateEventPlace($data, $id, $column = 'event_place_id') {
        $record = $this->_buildEventPlace($data);
        $where = $this->getDbTable(self::DB_EVENT_PLACE)->getAdapter()->quoteInto($column . ' = ?', $id);
        $tmp = $this->getDbTable(self::DB_EVENT_PLACE)->getByColumn($id, $column);
        $this->_updateImage($record, 'event_place', $tmp['event_place_id']);
        return $this->getDbTable(self::DB_EVENT_PLACE)->update($record, $where);
    }

    public function addEventPlace($data) {
        $record = $this->_buildEventPlace($data);
        $recordId = $this->getDbTable(self::DB_EVENT_PLACE)->insert($record);
        $this->_updateImage($record, 'event_place', $recordId);
        return $this->getDbTable(self::DB_EVENT_PLACE)->get($recordId);
    }

    public function updateEvent($data, $id, $column = 'event_id') {
        $record = $this->_buildEvent($data);
        $where = $this->getDbTable()->getAdapter()->quoteInto($column . ' = ?', $id);
        return $this->getDbTable()->update($record, $where);
    }

    public function addEvent($data) {
        $record = $this->_buildEvent($data);
        $recordId = $this->getDbTable()->insert($record);
        return $this->getDbTable()->get($recordId);
    }

    private function _updateImage($record, $sourceName, $sourceId, $imgIdCol = 'image_id') {
        if (!empty($record[$imgIdCol]) && $record[$imgIdCol] > 0) {
            $daoImage = new Application_Model_DAO_Image();
            $daoImage->getDbTable()->update(array(
                'source_name' => $sourceName,
                'source_id' => $sourceId,
                    ), (int) $record[$imgIdCol]);
        }
    }

    private function _buildEventInfo(array $data, $extra = null) {
        $record = array();
        $this->setSafety($record, $data, 'type');
        $this->setSafety($record, $data, 'name');
        $this->setSafety($record, $data, 'description');
        $this->setSafety($record, $data, 'image_id');

        if (!empty($extra)) {
            $record['extra_info'] = Zend_Json::encode($extra);
        }

        return $record;
    }

    private function _buildEventPlace(array $data) {
        $record = array();
        $this->setSafety($record, $data, 'type');
        $this->setSafety($record, $data, 'name');
        $this->setSafety($record, $data, 'description');
        $this->setSafety($record, $data, 'address');
        $this->setSafety($record, $data, 'city');
        $this->setSafety($record, $data, 'image_id');
        return $record;
    }

    private function _buildEvent(array $data) {
        $record = array();
        $this->setSafety($record, $data, 'event_info_id');
        $this->setSafety($record, $data, 'event_place_id');
        $this->setSafety($record, $data, 'start_date');
        $this->setSafety($record, $data, 'start_time');
        $this->setSafety($record, $data, 'end_date');
        $this->setSafety($record, $data, 'end_time');
        if (empty($record['start_time'])) {
            $record['start_time'] = null;
        }
        if (empty($record['end_date'])) {
            $record['end_date'] = null;
        }
        if (empty($record['end_time'])) {
            $record['end_time'] = null;
        }
        return $record;
    }

    protected function getDbTableNameMap() {
        return array(
            self::DB_EVENT => 'Application_Model_DbTable_Event',
            self::DB_EVENT_INFO => 'Application_Model_DbTable_EventInfo',
            self::DB_EVENT_PLACE => 'Application_Model_DbTable_EventPlace',
        );
    }

    protected function getDefaultDbTableName() {
        return self::DB_EVENT;
    }

}
